home *** CD-ROM | disk | FTP | other *** search
- Subject: v13i039: Public domaind M4 macro processor, Part02/02
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Ozan Yigit <yunexus!oz>
- Posting-number: Volume 13, Issue 39
- Archive-name: m4/part02
-
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create the files:
- # ack.m4
- # hanoi.m4
- # hash.m4
- # sqroot.m4
- # string.m4
- # test.m4
- # README
- # MANIFEST
- # m4.1
- export PATH; PATH=/bin:$PATH
- echo shar: extracting "'ack.m4'" '(121 characters)'
- if test -f 'ack.m4'
- then
- echo shar: will not over-write existing file "'ack.m4'"
- else
- sed 's/^ X//' << \SHAR_EOF > 'ack.m4'
- Xdefine(DECR,`eval($1-1)')
- Xdefine(ack, `ifelse($1,0,incr($2),$2,0,`ack(DECR($1),1)',
- X`ack(DECR($1), ack($1,DECR($2)))')')
- SHAR_EOF
- if test 121 -ne "`wc -c < 'ack.m4'`"
- then
- echo shar: error transmitting "'ack.m4'" '(should have been 121 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'hanoi.m4'" '(215 characters)'
- if test -f 'hanoi.m4'
- then
- echo shar: will not over-write existing file "'hanoi.m4'"
- else
- sed 's/^ X//' << \SHAR_EOF > 'hanoi.m4'
- Xdefine(DECR,`eval($1-1)')
- Xdefine(hanoi, `trans(A, B, C, $1)')
- X
- Xdefine(moved,`move disk from $1 to $2
- X')
- X
- Xdefine(trans, `ifelse($4,1,`moved($1,$2)',
- X `trans($1,$3,$2,DECR($4))moved($1,$2)trans($3,$2,$1,DECR($4))')')
- SHAR_EOF
- if test 215 -ne "`wc -c < 'hanoi.m4'`"
- then
- echo shar: error transmitting "'hanoi.m4'" '(should have been 215 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'hash.m4'" '(425 characters)'
- if test -f 'hash.m4'
- then
- echo shar: will not over-write existing file "'hash.m4'"
- else
- sed 's/^ X//' << \SHAR_EOF > 'hash.m4'
- Xdnl This probably will not run on any m4 that cannot
- Xdnl handle char constants in eval.
- Xdnl
- Xchangequote(<,>) define(HASHVAL,99) dnl
- Xdefine(hash,<eval(str(substr($1,1),0)%HASHVAL)>) dnl
- Xdefine(str,
- X <ifelse($1,",$2,
- X <str(substr(<$1>,1),<eval($2+'substr($1,0,1)')>)>)
- X >) dnl
- Xdefine(KEYWORD,<$1,hash($1),>) dnl
- Xdefine(TSTART,
- X<struct prehash {
- X char *keyword;
- X int hashval;
- X} keytab[] = {>) dnl
- Xdefine(TEND,< "",0
- X};>) dnl
- SHAR_EOF
- if test 425 -ne "`wc -c < 'hash.m4'`"
- then
- echo shar: error transmitting "'hash.m4'" '(should have been 425 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'sqroot.m4'" '(238 characters)'
- if test -f 'sqroot.m4'
- then
- echo shar: will not over-write existing file "'sqroot.m4'"
- else
- sed 's/^ X//' << \SHAR_EOF > 'sqroot.m4'
- Xdefine(square_root,
- X `ifelse(eval($1<0),1,negative-square-root,
- X `square_root_aux($1, 1, eval(($1+1)/2))')')
- Xdefine(square_root_aux,
- X `ifelse($3, $2, $3,
- X $3, eval($1/$2), $3,
- X `square_root_aux($1, $3, eval(($3+($1/$3))/2))')')
- SHAR_EOF
- if test 238 -ne "`wc -c < 'sqroot.m4'`"
- then
- echo shar: error transmitting "'sqroot.m4'" '(should have been 238 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'string.m4'" '(204 characters)'
- if test -f 'string.m4'
- then
- echo shar: will not over-write existing file "'string.m4'"
- else
- sed 's/^ X//' << \SHAR_EOF > 'string.m4'
- X
- Xdefine(string,`integer $1(len(substr($2,1)))
- Xstr($1,substr($2,1),0)
- Xdata $1(len(substr($2,1)))/EOS/
- X')
- X
- Xdefine(str,`ifelse($2,",,data $1(incr($3))/`LET'substr($2,0,1)/
- X`str($1,substr($2,1),incr($3))')')
- SHAR_EOF
- if test 204 -ne "`wc -c < 'string.m4'`"
- then
- echo shar: error transmitting "'string.m4'" '(should have been 204 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'test.m4'" '(7873 characters)'
- if test -f 'test.m4'
- then
- echo shar: will not over-write existing file "'test.m4'"
- else
- sed 's/^ X//' << \SHAR_EOF > 'test.m4'
- X#
- X# test file for mp (not comprehensive)
- X#
- X# include string macros
- X#
- Xinclude(string.m4)
- X#
- X# create some fortrash strings for an even uglier language
- X#
- Xstring(TEXT, "text")
- Xstring(DATA, "data")
- Xstring(BEGIN, "begin")
- Xstring(END, "end")
- Xstring(IF, "if")
- Xstring(THEN, "then")
- Xstring(ELSE, "else")
- Xstring(CASE, "case")
- Xstring(REPEAT, "repeat")
- Xstring(WHILE, "while")
- Xstring(DEFAULT, "default")
- Xstring(UNTIL, "until")
- Xstring(FUNCTION, "function")
- Xstring(PROCEDURE, "procedure")
- Xstring(EXTERNAL, "external")
- Xstring(FORWARD, "forward")
- Xstring(TYPE, "type")
- Xstring(VAR, "var")
- Xstring(CONST, "const")
- Xstring(PROGRAM, "program")
- Xstring(INPUT, "input")
- Xstring(OUTPUT, "output")
- X#
- Xdivert(2)
- Xdiversion #1
- Xdivert(3)
- Xdiversion #2
- Xdivert(4)
- Xdiversion #3
- Xdivert(5)
- Xdiversion #4
- Xdivert(0)
- Xdefine(abc,xxx)
- Xifdef(`abc',defined,undefined)
- X#
- X# v7 m4 does this wrong. The right output is
- X# this is A vEry lon sEntEnCE
- X# see m4 documentation for translit.
- X#
- Xtranslit(`this is a very long sentence', abcdefg, ABCDEF)
- X#
- X# include towers-of-hanoi
- X#
- Xinclude(hanoi.m4)
- X#
- X# some reasonable set of disks
- X#
- Xhanoi(6)
- X#
- X# include ackermann's function
- X#
- Xinclude(ack.m4)
- X#
- X# something like (3,3) will blow away un*x m4.
- X#
- Xack(2,3)
- X#
- X# include a square_root function for fixed nums
- X#
- Xinclude(sqroot.m4)
- X#
- X# some square roots.
- X#
- Xsquare_root(15)
- Xsquare_root(100)
- Xsquare_root(-4)
- Xsquare_root(21372)
- X#
- X# some textual material for enjoyment.
- X#
- X[taken from the 'Clemson University Computer Newsletter',
- X September 1981, pp. 6-7]
- X
- XI am a wizard in the magical Kingdom of Transformation and I
- Xslay dragons for a living. Actually, I am a systems programmer.
- XOne of the problems with systems programming is explaining to
- Xnon-computer enthusiasts what that is. All of the terms I use to
- Xdescribe my job are totally meaningless to them. Usually my response
- Xto questions about my work is to say as little as possible. For
- Xinstance, if someone asks what happened at work this week, I say
- X"Nothing much" and then I change the subject.
- X
- XWith the assistance of my brother, a mechanical engineer, I have devised
- Xan analogy that everyone can understand. The analogy describes the
- X"Kingdom of Transformation" where travelers wander and are magically
- Xtransformed. This kingdom is the computer and the travelers are information.
- XThe purpose of the computer is to change information to a more meaningful
- Xforma. The law of conservation applies here: The computer never creates
- Xand never intentionally destroys data. With no further ado, let us travel
- Xto the Kingdom of Transformation:
- X
- XIn a land far, far away, there is a magical kingdom called the Kingdom of
- XTransformation. A king rules over this land and employs a Council of
- XWizardry. The main purpose of this kingdom is to provide a way for
- Xneighboring kingdoms to transform citizens into more useful citizens. This
- Xis done by allowing the citizens to enter the kingdom at one of its ports
- Xand to travel any of the many routes in the kingdom. They are magically
- Xtransformed along the way. The income of the Kingdom of Transformation
- Xcomes from the many toll roads within its boundaries.
- X
- XThe Kingdom of Transformation was created when several kingdoms got
- Xtogether and discovered a mutual need for new talents and abilities for
- Xcitizens. They employed CTK, Inc. (Creators of Transformation, Inc.) to
- Xcreate this kingdom. CTK designed the country, its transportation routes,
- Xand its laws of transformation, and created the major highway system.
- X
- XHazards
- X=======
- X
- XBecause magic is not truly controllable, CTK invariably, but unknowingly,
- Xcreates dragons. Dragons are huge fire-breathing beasts which sometimes
- Xinjure or kill travelers. Fortunately, they do not travel, but always
- Xremain near their den.
- X
- XOther hazards also exist which are potentially harmful. As the roads
- Xbecome older and more weatherbeaten, pot-holes will develop, trees will
- Xfall on travelers, etc. CTK maintenance men are called to fix these
- Xproblems.
- X
- XWizards
- X=======
- X
- XThe wizards play a major role in creating and maintaining the kingdom but
- Xget little credit for their work because it is performed secretly. The
- Xwizards do not wan the workers or travelers to learn their incantations
- Xbecause many laws would be broken and chaos would result.
- X
- XCTK's grand design is always general enough to be applicable in many
- Xdifferent situations. As a result, it is often difficult to use. The
- Xfirst duty of the wizards is to tailor the transformation laws so as to be
- Xmore beneficial and easier to use in their particular environment.
- X
- XAfter creation of the kingdom, a major duty of the wizards is to search for
- Xand kill dragons. If travelers do not return on time or if they return
- Xinjured, the ruler of the country contacts the wizards. If the wizards
- Xdetermine that the injury or death occurred due to the traveler's
- Xnegligence, they provide the traveler's country with additional warnings.
- XIf not, they must determine if the cause was a road hazard or a dragon. If
- Xthe suspect a road hazard, they call in a CTK maintenance man to locate the
- Xhazard and to eliminate it, as in repairing the pothole in the road. If
- Xthey think that cause was a dragon, then they must find and slay it.
- X
- XThe most difficult part of eliminating a dragon is finding it. Sometimes
- Xthe wizard magically knows where the dragon's lair it, but often the wizard
- Xmust send another traveler along the same route and watch to see where he
- Xdisappears. This sounds like a failsafe method for finding dragons (and a
- Xsuicide mission for thr traveler) but the second traveler does not always
- Xdisappear. Some dragons eat any traveler who comes too close; others are
- Xvery picky.
- X
- XThe wizards may call in CTK who designed the highway system and
- Xtransformation laws to help devise a way to locate the dragon. CTK also
- Xhelps provide the right spell or incantation to slay the dragon. (There is
- Xno general spell to slay dragons; each dragon must be eliminated with a
- Xdifferent spell.)
- X
- XBecause neither CTK nor wizards are perfect, spells to not always work
- Xcorrectly. At best, nothing happens when the wrong spell is uttered. At
- Xworst, the dragon becomes a much larger dragon or multiplies into several
- Xsmaller ones. In either case, new spells must be found.
- X
- XIf all existing dragons are quiet (i.e. have eaten sufficiently), wizards
- Xhave time to do other things. They hide in castles and practice spells and
- Xincatations. They also devise shortcuts for travelers and new laws of
- Xtransformation.
- X
- XChanges in the Kingdom
- X======================
- X
- XAs new transformation kingdoms are created and old ones are maintained,
- XCTK, Inc. is constantly learning new things. It learns ways to avoid
- Xcreating some of the dragons that they have previously created. It also
- Xdiscovers new and better laws of transformation. As a result, CTK will
- Xperiodically create a new grand design which is far better than the old.
- XThe wizards determine when is a good time to implement this new design.
- XThis is when the tourist season is slow or when no important travelers
- X(VIPs) are to arrive. The kingdom must be closed for the actual
- Ximplementation and is leter reopened as a new and better place to go.
- X
- XA final question you might ask is what happens when the number of tourists
- Xbecomes too great for the kingdom to handle in a reasonable period of time
- X(i.e., the tourist lines at the ports are too long). The Kingdom of
- XTransformation has three options: (1) shorten the paths that a tourist must
- Xtravel, or (2) convince CTK to develop a faster breed of horses so that the
- Xtravelers can finish sooner, or (3) annex more territories so that the
- Xkingdom can handle more travelers.
- X
- XThus ends the story of the Kingdom of Transformation. I hope this has
- Xexplained my job to you: I slay dragons for a living.
- X
- X#
- X#should do an automatic undivert..
- X#
- SHAR_EOF
- if test 7873 -ne "`wc -c < 'test.m4'`"
- then
- echo shar: error transmitting "'test.m4'" '(should have been 7873 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'README'"
- if test -f 'README'
- then
- echo shar: will not over-write existing file "'README'"
- else
- cat << \SHAR_EOF > 'README'
- What you have here is a completely PD implementation of
- M4. It was originally written for the GNU project.
- This version was the last version before a major re-write
- took place.
-
- Pd M4 is based on software tools macro, as described in the
- two tools books by Kernighan and Plauger. Although some
- serious changes have been made, this version inherits the basic
- design problems of the original, hence the ugliness of the
- underlying code. [GNU version of this processor is re-designed
- in a much cleaner fashion, and is expected to be out before
- 1988. GNU version also includes an extensive texinfo document.]
-
- PDness:
-
- This code *is* PD. You (public) have all the rights to the code.
- [But this also means you (singular) do not have any *extra*
- rights to the code, hence it is impossible for you to restrict
- the use and distribution of this code in any way.]
-
- Dedication:
-
- This posting is a dedication to an old 750 that started out
- running 4.1BSD and had 1.5 meg, 1 dz11, and 2 Rk07 drives.
- It was named yetti [sic] by accident, and was managed by the
- author until its retirement few months ago. [the name yetti
- now identifies a different machine]
-
- Distribution + misc:
-
- The distribution includes a small test suite, the sources and
- a man page. texinfo document is not included. The makefile is
- pretty simple. See the makefile for configuration options.
- Try "make time" for some timing comparisons between your un*x
- m4 and the pd m4. [It should be slighly slower than V7 m4, and
- slightly faster than SV m4]. Make sure to set MBIN to indicate
- the location of un*x m4. See the test suite (test.m4) for some
- additional comments about pd m4 vs un*x m4.
-
- Some thoughts:
-
- M4 is a neat macro processor but probably a bit outdated by
- now. It does not need gratuitous additions, or "features", but
- a complete re-write. As it stands, it is powerful enough for
- most macro processing needs. We have, for example, used it to
- build a configuration language for DECNET under VMS. It can
- be a handy software engineering tool under most circumstances,
- and can displace a lot of meaningless little hacks written in
- C, pascal or whatever. [See some net postings for references.]
-
- Suggestions for hacking:
-
- If you want to hack M4 further, you may wish to implement the
- SV m4 "trace" facility, and extended (5-char) Comment/Quote
- definitions. This version also needs some dynamicity for its
- data structures, and the ability to handle multiple file names
- in the command line. If you want to add "features", you may wish
- to first think about implementing the "feature" as an M4 macro.
- If you really want to elevate this processor into a more state-of
- the-art tool, than you should probably re-write it. [But I have
- already done that, so you may wish to wait for the GNU version to
- get a head start.]
-
- Feedback:
-
- If you have any important fixes and/or speed improvements, I am
- much interested, since my new version inherits some code from this
- version. I am also interested in hearing about any unique applica-
- tions of M4. I am not interested in gratuitous hacks or "neat"
- kitchen-sink features.
-
- Contact:
-
- Usenet: [decvax|ihnp4]!utzoo!yunexus!oz ||
- ...seismo!mnetor!yunexus!oz
- Bitnet: oz@[yulibra|yuyetti].BITNET
- Phonet: [416] 736-5257 x 3976
-
-
- enjoy. oz
- SHAR_EOF
- fi # end of overwriting check
- echo shar: extracting "'MANIFEST'" '(230 characters)'
- if test -f 'MANIFEST'
- then
- echo shar: will not over-write existing file "'MANIFEST'"
- else
- sed 's/^ X//' << \SHAR_EOF > 'MANIFEST'
- Xmdef.h - definitions and structures
- Xmain.c - this file: driver routines
- Xeval.c - general macro evaluator
- Xserv.c - service routines (doxxxx)
- Xmisc.c - miscellaneous routines
- Xexpr.c - expression parser
- Xlook.c - hash table management
- SHAR_EOF
- if test 230 -ne "`wc -c < 'MANIFEST'`"
- then
- echo shar: error transmitting "'MANIFEST'" '(should have been 230 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'m4.1'" '(9644 characters)'
- if test -f 'm4.1'
- then
- echo shar: will not over-write existing file "'m4.1'"
- else
- sed 's/^ X//' << \SHAR_EOF > 'm4.1'
- X.TH M4 local "30 Aug 1987"
- X.DA 08 Jan 1986
- X.SH NAME
- Xpd m4 \- macro processor
- X.SH ORIGIN
- XMetaSystems
- X.SH SYNOPSIS
- X.BI m4 "[ options ]"
- X.SH DESCRIPTION
- X.I Pd M4
- Xis a un*x M4 look-alike macro processor
- Xintended as a front end for Ratfor, Pascal, and other languages that do not
- Xhave a built-in macro processing capability.
- XPd M4 reads standard input, the processed text is written on the standard output.
- X.PP
- XThe options and their effects are as follows:
- X.TP
- X\f3\-D\fP\f2name\^\fP[\f3=\fP\f2val\^\fP]
- XDefines
- X.I name
- Xto
- X.I val
- Xor to null in
- X.IR val 's
- Xabsence.
- X.TP
- X.BI \-U name
- Xundefines
- X.IR name .
- X.PP
- XMacro calls
- Xhave the form:
- X.PP
- X.RS
- X\fBname\fI(arg1,arg2, .\|.\|., argn)\fR
- X.RE
- X.PP
- XThe
- X.B (
- Xmust immediately follow the name of the macro.
- XIf the name of a defined macro is not followed by a
- X.BR ( ,
- Xit is taken to be a call of that macro with no arguments, i.e. name().
- XPotential macro names consist of alphabetic letters and digits.
- X.PP
- XLeading unquoted blanks, tabs and newlines are ignored while collecting
- Xarguments.
- XLeft and right single quotes are used to quote strings.
- XThe value of a quoted string is the string stripped of the quotes.
- X.PP
- XWhen a macro name is recognized,
- Xits arguments are collected by searching for a matching
- X.BR ) .
- XIf fewer arguments are supplied than are in the macro definition,
- Xthe trailing arguments are taken to be null.
- XMacro evaluation proceeds normally during the collection of the arguments,
- Xand any commas or right parentheses
- Xwhich happen to turn up within the value of a nested
- Xcall are as effective as those in the original input text. (This is typically
- Xreferred as
- X.I inside-out
- Xmacro expansion.)
- XAfter argument collection,
- Xthe value of the macro is pushed back onto the input stream
- Xand rescanned.
- X.PP
- X.I Pd M4
- Xmakes available the following built-in macros.
- XThey may be redefined, but once this is done the original meaning is lost.
- XTheir values are null unless otherwise stated.
- X.de MC
- X.TP 14
- X.B \\$1
- Xusage: \\fI\\$1\\$2\\fR
- X.br
- X..
- X.MC define "(name [, val])"
- Xthe second argument is installed as the value of the macro
- Xwhose name is the first argument. If there is no second argument,
- Xthe value is null.
- XEach occurrence of
- X.BI $ n
- Xin the replacement text,
- Xwhere
- X.I n
- Xis a digit,
- Xis replaced by the
- X.IR n -th
- Xargument.
- XArgument 0 is the name of the macro;
- Xmissing arguments are replaced by the null string.
- X.MC defn "(name [, name ...])
- Xreturns the quoted definition of its argument(s). Useful in renaming
- Xmacros.
- X.MC undefine "(name [, name ...])"
- Xremoves the definition of the macro(s) named. If there is
- Xmore than one definition for the named macro, (due to previous use of
- X.IR pushdef )
- Xall definitions are removed.
- X.MC pushdef "(name [, val])"
- Xlike
- X.IR define ,
- Xbut saves any previous definition by stacking the current definition.
- X.MC popdef "(name [, name ...])"
- Xremoves current definition of its argument(s),
- Xexposing the previous one if any.
- X.MC ifdef "(name, if-def [, ifnot-def])"
- Xif the first argument is defined, the value is the second argument,
- Xotherwise the third.
- XIf there is no third argument, the value is null.
- XA word indicating the current operating system is predefined.
- X(e.g.
- X.I unix
- Xor
- X.IR vms )
- X.MC shift "(arg, arg, arg, ...)"
- Xreturns all but its first argument.
- XThe other arguments are quoted and pushed back with
- Xcommas in between.
- XThe quoting nullifies the effect of the extra scan that
- Xwill subsequently be performed.
- X.MC changequote "(lqchar, rqchar)"
- Xchange quote symbols to the first and second arguments.
- XWith no arguments, the quotes are reset back to the default
- Xcharacters. (i.e., \*`\|\*').
- X.MC changecom "(lcchar, rcchar)"
- Xchange left and right comment markers from the default
- X.B #
- Xand
- X.BR newline .
- XWith no arguments, the comment mechanism is reset back to
- Xthe default characters.
- XWith one argument, the left marker becomes the argument and
- Xthe right marker becomes newline.
- XWith two arguments, both markers are affected.
- X.MC divert "(divnum)"
- X.I m4
- Xmaintains 10 output streams,
- Xnumbered 0-9. initially stream 0 is the current stream.
- XThe
- X.I divert
- Xmacro changes the current output stream to its (digit-string)
- Xargument.
- XOutput diverted to a stream other than 0 through 9
- Xdisappears into bitbucket.
- X.MC undivert "([divnum [, divnum ...]])"
- Xcauses immediate output of text from diversions named as
- Xargument(s), or all diversions if no argument.
- XText may be undiverted into another diversion.
- XUndiverting discards the diverted text. At the end of input processing,
- X.I M4
- Xforces an automatic
- X.IR undivert ,
- Xunless
- X.I m4wrap
- Xis defined.
- X.MC divnum "()"
- Xreturns the value of the current output stream.
- X.MC dnl "()"
- Xreads and discards characters up to and including the next newline.
- X.MC ifelse "(arg, arg, if-same [, ifnot-same | arg, arg ...])"
- Xhas three or more arguments.
- XIf the first argument is the same string as the second,
- Xthen the value is the third argument.
- XIf not, and if there are more than four arguments, the process is
- Xrepeated with arguments 4, 5, 6 and 7.
- XOtherwise, the value is either the fourth string, or, if it is not present,
- Xnull.
- X.MC incr "(num)"
- Xreturns the value of its argument incremented by 1.
- XThe value of the argument is calculated
- Xby interpreting an initial digit-string as a decimal number.
- X.MC decr "(num)"
- Xreturns the value of its argument decremented by 1.
- X.MC eval "(expression)"
- Xevaluates its argument as a constant expression, using integer arithmetic.
- XThe evaluation mechanism is very similar to that of
- X.I cpp
- X(#if expression).
- XThe expression can involve only integer constants and character constants,
- Xpossibly connected by the binary operators
- X.nf
- X.ft B
- X
- X* / % + - >> << < >
- X<= >= == != & ^ | && ||
- X
- X.ft R
- X.fi
- Xor the unary operators \fB\- ~ !\fR
- Xor by the ternary operator \fB ? : \fR.
- XParentheses may be used for grouping. Octal numbers may be specified as
- Xin C.
- X.MC len "(string)"
- Xreturns the number of characters in its argument.
- X.MC index "(search-string, string)"
- Xreturns the position in its first argument where the second argument
- Xbegins (zero origin),
- Xor \-1 if the second argument does not occur.
- X.MC substr "(string, index [, length])"
- Xreturns a substring of its first argument.
- XThe second argument is a zero origin
- Xnumber selecting the first character (internally treated as an expression);
- Xthe third argument indicates the length of the substring.
- XA missing third argument is taken to be large enough to extend to
- Xthe end of the first string.
- X.MC translit "(source, from [, to])"
- Xtransliterates the characters in its first argument
- Xfrom the set given by the second argument to the set given by the third.
- XIf the third argument is shorter than the second, all extra characters
- Xin the second argument are deleted from the first argument. If the third
- Xargument is missing altogether, all characters in the second argument are
- Xdeleted from the first argument.
- X.MC include "(filename)"
- Xreturns the contents of the file named in the argument.
- X.MC sinclude "(filename)"
- Xis identical to
- X.IR include ,
- Xexcept that it
- Xsays nothing if the file is inaccessible.
- X.MC paste "(filename)"
- Xreturns the contents of the file named in the argument without any
- Xprocessing, unlike
- X.IR include.
- X.MC spaste "(filename)"
- Xis identical to
- X.IR paste ,
- Xexcept that it says nothing if the file is inaccessible.
- X.MC syscmd "(command)"
- Xexecutes the
- X.SM UNIX
- Xcommand given in the first argument.
- XNo value is returned.
- X.MC sysval "()"
- Xis the return code from the last call to
- X.IR syscmd .
- X.MC maketemp "(string)"
- Xfills in a string of
- X.SM XXXXXX
- Xin its argument with the current process
- X.SM ID\*S.
- X.MC m4exit "([exitcode])"
- Xcauses immediate exit from
- X.IR m4 .
- XArgument 1, if given, is the exit code;
- Xthe default is 0.
- X.MC m4wrap "(m4-macro-or-built-in)"
- Xargument 1 will be pushed back at final
- X.BR EOF ;
- Xexample: m4wrap(`dumptable()').
- X.MC errprint "(str [, str, str, ...])"
- Xprints its argument(s) on stderr. If there is more than one argument,
- Xeach argument is separated by a space during the output.
- X.MC dumpdef "([name, name, ...])"
- Xprints current names and definitions,
- Xfor the named items, or for all if no arguments are given.
- X.dt
- X.SH AUTHOR
- XOzan S. Yigit (oz)
- X.SH BUGS
- XPd M4 is distributed at the source level, and does not require an expensive
- Xlicense agreement.
- X.PP
- XA sufficiently complex M4 macro set is about as readable
- Xas
- X.BR APL .
- X.PP
- XAll complex uses of M4 require the ability to program in deep recursion.
- XPrevious lisp experience is recommended.
- X.PP
- XPd M4 is slower than V7 M4.
- X.SH EXAMPLES
- X.PP
- XThe following macro program illustrates the type of things that
- Xcan be done with M4.
- X.PP
- X.RS
- X.nf
- X\fBchangequote\fR(<,>) \fBdefine\fR(HASHVAL,99) \fBdnl\fR
- X\fBdefine\fR(hash,<\fBexpr\fR(str(\fBsubstr\fR($1,1),0)%HASHVAL)>) \fBdnl\fR
- X\fBdefine\fR(str,
- X <\fBifelse\fR($1,",$2,
- X <str(\fBsubstr\fR(<$1>,1),<\fBexpr\fR($2+'\fBsubstr\fR($1,0,1)')>)>)
- X >) \fBdnl\fR
- X\fBdefine\fR(KEYWORD,<$1,hash($1),>) \fBdnl\fR
- X\fBdefine\fR(TSTART,
- X<struct prehash {
- X char *keyword;
- X int hashval;
- X} keytab[] = {>) \fBdnl\fR
- X\fBdefine\fR(TEND,< "",0
- X};>) \fBdnl\fR
- X.fi
- X.RE
- X.PP
- XThus a keyword table containing the keyword string and its pre-calculated
- Xhash value may be generated thus:
- X.PP
- X.RS
- X.nf
- XTSTART
- X KEYWORD("foo")
- X KEYWORD("bar")
- X KEYWORD("baz")
- XTEND
- X.fi
- X.RE
- X.PP
- Xwhich will expand into:
- X.RS
- X.nf
- Xstruct prehash {
- X char *keyword;
- X int hashval;
- X} keytab[] = {
- X "foo",27,
- X "bar",12,
- X "baz",20,
- X "",0
- X};
- X.fi
- X.RE
- X.PP
- XPresumably, such a table would speed up the installation of the
- Xkeywords into a dynamic hash table. (Note that the above macro
- Xcannot be used with
- X.IR M4 ,
- Xsince
- X.B eval
- Xdoes not handle character constants.)
- X
- X.SH SEE ALSO
- Xcc(1),
- Xm4(1),
- Xcpp(1).
- X.I "The M4 Macro Processor\^"
- Xby B. W. Kernighan and D. M. Ritchie.
- X
- SHAR_EOF
- if test 9644 -ne "`wc -c < 'm4.1'`"
- then
- echo shar: error transmitting "'m4.1'" '(should have been 9644 characters)'
- fi
- fi # end of overwriting check
- # End of shell archive
-